﻿namespace Bridge.Base.Constructs
{
    using System;
    using System.ComponentModel;

    /// <summary>
    /// Class for implementing an object that has changable properties that need to notify any watching
    /// methods.
    /// </summary>
    [Serializable]
    public class ChangableObject : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Members

        /// <summary>
        /// Event called when a property changed.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        /// <summary>
        /// Called when a property is suspected to be changed. Notifies all watching structures if this is the case.
        /// </summary>
        /// <typeparam name="T">Type of property.</typeparam>
        /// <param name="propertyName">Name of the property that changed.</param>
        /// <param name="oldValue">Old value of the property.</param>
        /// <param name="newValue">New value of the property.</param>
        protected bool CheckPropertyChanged<T>(string propertyName, ref T oldValue, ref T newValue)
        {
            if (propertyName == null) throw new ArgumentNullException("propertyName");
            if (propertyName.Length == 0) throw new ArgumentException("propertyName cannot be empty.", "propertyName");

            if ((oldValue == null && newValue != null) || (oldValue != null && newValue == null) || (oldValue != null && newValue != null && !oldValue.Equals(newValue)))
            {
                oldValue = newValue;

                NotifyPropertyChanged(propertyName);
                return true;
            }
            return false;
        }

        /// <summary>
        /// Notifies all watcher objects that a property has changed.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (propertyName == null) throw new ArgumentNullException("propertyName");
            if (propertyName.Length == 0) throw new ArgumentException("propertyName cannot be empty.", "propertyName");

            PropertyChangedEventHandler eventHandler = PropertyChanged;
            if (eventHandler != null)
            {
                eventHandler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }
}
